package com.huawei.lynnbit.tool.cocos.processor.preset;

import com.huawei.lynnbit.tool.cocos.config.game.CocosVersion;
import com.huawei.lynnbit.tool.cocos.config.game.GameConfig;
import com.huawei.lynnbit.tool.cocos.config.game.task.CmdTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.Stage;
import com.huawei.lynnbit.tool.cocos.config.game.task.Task;
import com.huawei.lynnbit.tool.cocos.processor.Processor;
import com.huawei.lynnbit.tool.cocos.processor.leaf.CmdProcessor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class ExportProcessor implements Processor {
    private GameConfig gameConfig;

    public ExportProcessor(GameConfig gameConfig) {
        this.gameConfig = gameConfig;
    }

    @Override
    public void process() throws Exception {
        if (StringUtils.isBlank(gameConfig.getProjectPath())) {
            log.info("no config projectPath, skip export");
            return;
        }
        log.info("start to update cocos and export harmonyos next project >>>>>>>>>>>>>>>>>>>>>>>>");
        if (Objects.isNull(gameConfig.getCocosVersion())) {
            gameConfig.setCocosVersion(CocosVersion.forName(getCocosVersion()));
        }

        if (Objects.isNull(gameConfig.getCocosVersion())) {
            log.error("the cocos version: {} is not valid", getCocosVersion());
            throw new IllegalStateException("get cocos version failed");
        }

        if (CocosVersion.COCOS2.equals(gameConfig.getCocosVersion())) {
            CmdTask cocos2CmdExportTask = CmdTask.builder()
                    .stage(Stage.EXPORT)
                    .type(Task.TYPE_CMD)
                    .runCmd(gameConfig.getSystemConfig().getCocosCreator2Path() + " --path " + gameConfig.getProjectPath() + " --build " + get2BuildOptions()).build();

            new CmdProcessor(cocos2CmdExportTask, gameConfig).process();
        } else if (CocosVersion.COCOS3.equals(gameConfig.getCocosVersion())) {
            CmdTask cocos3CmdExportTask = CmdTask.builder()
                    .stage(Stage.EXPORT)
                    .type(Task.TYPE_CMD)
                    .runCmd(gameConfig.getSystemConfig().getCocosCreator3Path() + " --project " + gameConfig.getProjectPath() + " --build " + get3BuildOptions()).build();

            new CmdProcessor(cocos3CmdExportTask, gameConfig).process();
        } else {
            log.error("no possible to this branch");
            throw new IllegalStateException("no possible to this branch");
        }
    }

    private String get2BuildOptions() {
        StringBuilder sb = new StringBuilder("\"platform=harmonyos-next;appABIs=['arm64-v8a'];");
        if (StringUtils.isNotBlank(gameConfig.getAppInfo().getAppName())) {
            sb.append("title=").append(gameConfig.getAppInfo().getAppName()).append(";");
        }
        // cocos2 startscene是uuid："startScene": "9b45bd29-0c54-400d-a5d9-b66a8f6f89f6",
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getInitialScene())) {
            sb.append("startScene=").append(gameConfig.getExportInfo().getInitialScene()).append(";");
        }
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getOrientation())) {
            if (gameConfig.getExportInfo().isPortrait()) {
                sb.append("orientation={'portrait':true,'landscapeLeft':false,'landscapeRight':false,'upsideDown':false};");
            } else {
                sb.append("orientation={'portrait':false,'landscapeLeft':true,'landscapeRight':true,'upsideDown':false};");
            }
        }
        if (StringUtils.isNotBlank(gameConfig.getAppInfo().getPackageName())) {
            sb.append("packageName=").append(gameConfig.getAppInfo().getPackageName()).append(";");
        }
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getJsEngine())) {
            sb.append("harmonyos-next={'jsEngine':'").append(gameConfig.getExportInfo().getJsEngine()).append("'");
            if (StringUtils.isNotBlank(gameConfig.getAppInfo().getPackageName())) {
                sb.append(",'packageName':'").append(gameConfig.getAppInfo().getPackageName()).append("'");
            }
            sb.append("};");
        }

        return sb.append("\"").toString();
    }

    private String get3BuildOptions() {
        StringBuilder sb = new StringBuilder("\"platform=harmonyos-next;");
        if (StringUtils.isNotBlank(gameConfig.getAppInfo().getAppName())) {
            sb.append("name=").append(gameConfig.getAppInfo().getAppName()).append(";");
        }

        // cocos3 startscene是路径："startScene": "db://assets/scene.scene",
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getInitialScene())) {
            sb.append("startScene=").append(gameConfig.getExportInfo().getInitialScene()).append(";");
        }

        sb.append("packages={'harmonyos-next':{'appABIs':['arm64-v8a'],");
        if (StringUtils.isNotBlank(gameConfig.getAppInfo().getPackageName())) {
            sb.append("'packageName':'").append(gameConfig.getAppInfo().getPackageName()).append("',");
        }
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getOrientation())) {
            if (gameConfig.getExportInfo().isPortrait()) {
                sb.append("'orientation':{'portrait':true,'landscapeLeft':false,'landscapeRight':false,'upsideDown':false},");
            } else {
                sb.append("'orientation':{'portrait':false,'landscapeLeft':true,'landscapeRight':true,'upsideDown':false},");
            }
        }
        if (StringUtils.isNotBlank(gameConfig.getExportInfo().getJsEngine())) {
            sb.append("'jsEngine':'").append(gameConfig.getExportInfo().getJsEngine()).append("',");
        }

        return sb.substring(0, sb.length() - 1) + "}}\"";
    }

    private String getCocosVersion() throws IOException {
        String version = getVersion(gameConfig.getProjectPath() + "\\project.json");
        if (StringUtils.isNotBlank(version)) {
            return version;
        }

        version = getVersion(gameConfig.getProjectPath() + "\\package.json");
        if (StringUtils.isNotBlank(version)) {
            return version;
        }

        log.error("the Path: {} is not a cocos path, do not have project.json/package.json file", gameConfig.getProjectPath());
        throw new IllegalStateException("get cocos version failed");
    }

    private String getVersion(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            log.warn("try to get cocos version from {} failed, the file is not exist", filePath);
            return StringUtils.EMPTY;
        }

        String projectStr = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
        Pattern pattern = Pattern.compile("\"version\"\s*:\s*\"(.*)\"");
        Matcher matcher = pattern.matcher(projectStr);
        if (matcher.find()) {
            return matcher.group(1);
        } else {
            log.warn("try to get cocos version from {} failed, match pattern failed", filePath);
            return StringUtils.EMPTY;
        }
    }
}